﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Intex.Db.Models;
using ServiceStack.OrmLite;
using ServiceStack.Common.Utils;
using System.Diagnostics;

namespace Intex.Db.Service
{
    public class ItemService
    {
        private Code39 code = new Code39();
        //private static RecoveryService rService = new RecoveryService();
        public static List<long> ImportIds;

        //public static void ResetMode()
        //{
        //    rService.IsRecoveryMode = false;
        //}

        public bool ImportDatas(List<TableItem> datas)
        {
            if (!datas.Any()) return true;
            ImportIds = new List<long>();
            using (var context = new DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                var typeDict = new Dictionary<string, ItemType>();
                var lastItem = context.Items.First<Models.Item>("Order by ItemId desc");
                int itemId = lastItem.ItemId + 1;
                foreach (var item in typeList)
                {
                    typeDict.Add(item.Alias, item);
                }
                foreach (var item in datas)
                {
                    var model = new Item();
                    model.Name = item.ItemName;
                    if (item.Datas.ContainsKey("CreatedDate"))
                    {
                        model.CreatedDate = DateTime.Parse(item.Datas["CreatedDate"]);
                        item.Datas.Remove("CreatedDate");
                    }
                    context.Items.Insert<Item>(model);
                    foreach (var cell in item.Datas)
                    {
                        if (!typeDict.ContainsKey(cell.Key))
                        {
                            continue;
                        }
                        var value = new ItemValue();
                        value.ItemId = itemId;
                        value.ItemTypeId = typeDict[cell.Key].ItemTypeId;
                        //value.Value = ItemValueFacory.ConvertToValue(typeDict[cell.Key].ItemDataType, cell.Value, typeDict[cell.Key], item);
                        value.Value = cell.Value;
                        context.Items.Insert<ItemValue>(value);
                    }
                    ImportIds.Add(itemId);
                    itemId++;
                }
            }
            return true;
        }

        public Dictionary<string, string> GetItemTypes()
        {
            var dict = new Dictionary<string, string>();
            using (DbContext context = new DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType --where ItemDataType where ItemDataType not like 'ImportData%'");
                foreach (var item in typeList)
                {
                    dict.Add(item.Alias, item.ItemName);
                }
            }
            return dict;
        }

        public bool ImportDatas(DataTable dt)
        {
            if (dt.Rows.Count < 1) return true;
            ImportIds = new List<long>();
            using (DbContext context = new DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                var typeDict = new Dictionary<string, ItemType>();
                foreach (var item in typeList)
                {
                    typeDict.Add(item.Alias, item);
                }

                var columnNames = new List<string>();
                foreach (DataColumn dr in dt.Columns)
                {
                    columnNames.Add(dr.ColumnName);
                }
                columnNames.Remove(Config.NameAlias);
                columnNames.Remove(Config.CreatedAlias);
                var tran = context.Items.BeginTransaction();
                foreach (DataRow row in dt.Rows)
                {                    
                    var model = new Item();
                    model.Name = row[Config.NameAlias].ToString();
                    if (string.IsNullOrEmpty(model.Name) || model.Name.Trim() == "0") continue;
                    model.CreatedDate = DateTime.Parse(row[Config.CreatedAlias].ToString());
                    context.Items.Insert<Item>(model);
                    long itemId = context.Items.GetLastInsertId();
                    foreach (var item in columnNames)
                    {
                        if (!typeDict.ContainsKey(item))
                        {
                            continue;
                        }
                        var value = new ItemValue();
                        value.ItemId = (int)itemId;
                        value.ItemTypeId = typeDict[item].ItemTypeId;
                        //value.Value = ItemValueFacory.ConvertToValue(typeDict[item].ItemDataType, row[item], typeDict[item], row);
                        value.Value = row[item].ToString();
                        if (string.IsNullOrEmpty(value.Value)) continue;
                        context.Items.Insert<ItemValue>(value);
                    }
                    ImportIds.Add(itemId);
                }
                tran.Commit();
                tran.Dispose();
            }
            return true;
        }

        public List<string> CheckIndex(DataTable dt)
        {
            List<string> repeatIndexs = new List<string>();
            if (dt.Rows.Count < 1) return repeatIndexs;
            DataRow dr = dt.Rows[0];
            DateTime date = DateTime.Parse(dr[Config.CreatedAlias].ToString());
            List<string> indexs = new List<string>();
            using (DbContext context = new DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                int indexTypeId = typeList.First(x => x.Alias == Config.IndexAlias).ItemTypeId;
                foreach (DataRow dRow in dt.Rows)
                {
                    indexs.Add(dRow[Config.IndexAlias].ToString());
                }
                string sql = "select iv.Value as Value from Item i inner join ItemValue iv on i.ItemId = iv.ItemId and iv.ItemTypeId={2} and iv.Value in ({1}) where CreatedDate like '{0}%'";
                sql = string.Format(sql, date.ToString("yyyy-MM-dd"), string.Join(",", indexs), indexTypeId);
                var tempModels = context.Items.Select<RepIndexModel>(sql);
                repeatIndexs = tempModels.Select(x => x.Value).ToList();
            }
            return repeatIndexs;
        }

        public bool InsertAt(DataTable dt, int index)
        {
            if (dt.Rows.Count < 1) return false;
            DataRow dr = dt.Rows[0];
            DateTime date = DateTime.Parse(dr[Config.CreatedAlias].ToString());
            int startIndex = int.Parse(dr[Config.IndexAlias].ToString());
            if (startIndex != index + 1)
            {
                startIndex = index + 1;
                foreach (DataRow dRow in dt.Rows)
                {
                    dRow[Config.IndexAlias] = startIndex;
                    startIndex++;
                }
            }
            using (DbContext context = new DbContext())
            {
                string sql = "update ItemValue set Value=Value+{3}   where ItemTypeId ={1} and Value + 1 > {0} and ItemId in (select ItemId from Item where CreatedDate like '{2}%');";
                var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                int indexTypeId = typeList.First(x => x.Alias == Config.IndexAlias).ItemTypeId;
                sql = string.Format(sql, index + 1, indexTypeId, date.ToString("yyyy-MM-dd"), dt.Rows.Count);
                context.Items.ExecuteSql(sql);
            }
            return ImportDatas(dt);
        }

        public List<string> GetTemplateValues()
        {
            using (DbContext context = new DbContext())
            {
                string sql = "select * from ItemTemplate";
                List<ItemTemplate> templates = context.Items.Select<ItemTemplate>(sql);
                var result = templates.Select(x => x.ItemTemplateName).ToList();
                return result.Distinct().ToList();
            }
        }

        public DataTable GetTemplateValue(string templateName, out Dictionary<string,ItemType> map)
        {
            DataTable dt = new DataTable();
            map = new Dictionary<string, ItemType>();
            using (DbContext context = new DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType");
                List<string> columns = Config.GetShowConlum("Print");
                List<TemplateViewModel> list = context.Items.Select<TemplateViewModel>(string.Format(TemplateViewModel.QUERYALL, "'" + templateName + "'"));
                Dictionary<int, int> map0 = new Dictionary<int, int>();
                Dictionary<int, ItemType> typeDict = new Dictionary<int, ItemType>();
                foreach (var item in typeList)
                {                    
                    map.Add(item.Alias, item);
                    typeDict.Add(item.ItemTypeId, item);
                }
               // dt.Columns.Add(new DataColumn("PrintStatus"));
                //dt.Columns.Add(new DataColumn("ItemId"));
                dt.Columns.Add(new DataColumn("TemplateFile"));
                //dt.Columns.Add(new DataColumn("打印状态"));
                foreach (var item in list)
                {
                    DataRow dr;
                    if (!columns.Contains(typeDict[item.ItemType].Alias)) continue;
                    if (!dt.Columns.Contains(typeDict[item.ItemType].ItemName))
                    {
                        dt.Columns.Add(typeDict[item.ItemType].ItemName);
                    } 
                    if (!map0.ContainsKey(item.Id))
                    {
                        dr = dt.NewRow();
                        map0.Add(item.Id, dt.Rows.Count);
                        dt.Rows.Add(dr);
                    }
                    else
                    {
                        dr = dt.Rows[map0[item.Id]];
                    }
                    dr[typeDict[item.ItemType].ItemName] = item.Value;
                    dr["TemplateFile"] = item.TemplateFile;
                }
            }
            return dt;
        }

        public bool ChangeIndex(DateTime date, int source, int target)
        {
            using (DbContext context = new DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                int indexTypeId = typeList.First(x => x.Alias == Config.IndexAlias).ItemTypeId;
                string sql = "select iv.* from Item i inner join ItemValue iv on i.ItemId = iv.ItemId and iv.ItemTypeId={2} and iv.Value in ({1}) where CreatedDate like '{0}%'";
                string ids = string.Format("{0},{1}", source, target);
                sql = string.Format(sql, date.ToString("yyyy-MM-dd"), ids, indexTypeId);
                var itemValues = context.Items.Select<ItemValue>(sql);
                if (itemValues[0].Value == source.ToString())
                {
                    itemValues[0].Value = target.ToString();
                    itemValues[1].Value = source.ToString();
                }
                else
                {
                    itemValues[1].Value = target.ToString();
                    itemValues[0].Value = source.ToString();
                }
                try
                {
                    var tran = context.Items.BeginTransaction();
                    //context.Items.Delete<ItemValue>(itemValues[0], itemValues[1]);
                    context.Items.Update<ItemValue>(itemValues[0]);
                    context.Items.Update<ItemValue>(itemValues[1]);
                    tran.Commit();
                    tran.Dispose();
                }
                catch (Exception e)
                {
                    return false;
                }
            }
            return true;
        }

        public bool DeleteItemValues(List<string> indexes, DateTime date)
        {
            if (indexes == null || !indexes.Any()) return true;
            if (date == null) return false;
            using (DbContext context = new DbContext())
            {
                try
                {
                    string sql = "select i.ItemId from Item i inner join ItemValue iv on i.ItemId = iv.ItemId and iv.ItemTypeId={2} and iv.Value in ({1}) where CreatedDate like '{0}%'";
                    var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                    int indexTypeId = typeList.First(x => x.Alias == Config.IndexAlias).ItemTypeId;
                    sql = string.Format(sql, date.ToString("yyyy-MM-dd"), string.Join(",", indexes), indexTypeId);
                    var tempIds = context.Items.Select<ItemIdModel>(sql);
                    List<int> itemIds = tempIds.Select(x => x.ItemId).ToList();
                    var tran = context.Items.BeginTransaction();
                    sql = string.Format("ItemId in ({0})", string.Join(",", itemIds));
                    context.Items.Delete<ItemValue>(sql);
                    context.Items.Delete<Item>(sql);
                    tran.Commit();
                    tran.Dispose();
                }
                catch (Exception e)
                {
                    return false;
                }
            }
            return true;
        }

        public bool DeleteItemValues(List<int> itemIds, int firstIndex, DateTime date)
        {
            using (DbContext context = new DbContext())
            {
                try
                {
                    string sql = string.Format("ItemId in ({0})", string.Join(",", itemIds));
                    var tran = context.Items.BeginTransaction();
                    context.Items.Delete<ItemValue>(sql);
                    context.Items.Delete<Item>(sql);
                    sql = "update ItemValue set Value=Value-{3} where ItemTypeId ={1} and Value +1 > {0} and ItemId in (select ItemId from Item where CreatedDate like '{2}%');";
                    var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType like 'ImportData%'");
                    int indexTypeId = typeList.First(x => x.Alias == Config.IndexAlias).ItemTypeId;
                    sql = string.Format(sql, firstIndex + 1, indexTypeId, date.ToString("yyyy-MM-dd"), itemIds.Count);
                    context.Items.ExecuteSql(sql);
                    tran.Commit();
                    tran.Dispose();
                }
                catch (Exception e)
                {
                    return false;
                }
            }
            return true;
        }

        private string getVMSql(DateTime? filter, ref List<long> ids)
        {
            string datefilter = "";
            string sql = "";
            if (filter != null)
            {
                DateTime before = filter.Value;
                datefilter = string.Format("im.CreatedDate like '{0}%'", before.ToString("yyyy-MM-dd"));
                sql = datefilter;
                ids = new List<long>();
            }
            else
            {
                if (ids == null)
                {
                    ids = new List<long>();
                    sql = "";
                }
                else
                {
                    sql = string.Join(",", ids);
                }
                sql = string.Format("im.ItemId in ({0})", sql);
            }
            return sql;
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="columns">需要用到的列</param>
        /// <param name="isDisplay">true用于窗口显示，false用于打印</param>
        /// <param name="map">字段对照表</param>
        /// <param name="ids">需要的数据的id，为null直接使用刚导入的数据</param>
        /// <param name="filter">查询日期</param>
        /// <returns>数据列表</returns>
        public DataTable GetDatas(bool isDisplay, out Dictionary<string, ItemType> map, out Dictionary<int, int> orderList, List<long> ids = null, DateTime? filter = null)
        {
            List<string> columns;
            PMS.Log.Logger.Info("Query DataBase");
            orderList = new Dictionary<int, int>();
            if (isDisplay)
            {
                columns = Config.GetShowConlum("Show");
            }
            else
            {
                columns = Config.GetShowConlum("Print");
            }

            if (ids == null && filter == null) ids = ImportIds;
            DataTable dt = new DataTable();
            map = new Dictionary<string, ItemType>();
            using (var context = new Db.Models.DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType");
                var mapDict = new Dictionary<string, string>();
                var typeDict = new Dictionary<int, ItemType>();
                foreach (var item in typeList)
                {
                    if (!columns.Contains(item.Alias)) continue;
                    typeDict.Add(item.ItemTypeId, item);
                    mapDict.Add(item.Alias, item.ItemName);
                    map.Add(item.Alias, item);
                }
                foreach (var item in columns)
                {
                    dt.Columns.Add(new DataColumn(mapDict[item]));
                }
                dt.Columns.Add(new DataColumn("PrintStatus"));
                dt.Columns.Add(new DataColumn("ItemId"));
                dt.Columns.Add(new DataColumn("TemplateFile"));
                dt.Columns.Add(new DataColumn("打印状态"));
                string sql = getVMSql(filter,ref ids);               
                var typeIds = string.Join(",", typeDict.Keys.ToList());
                var items = context.Items.Select<ItemViewModel>(string.Format(ItemViewModel.QUERYSQL, sql, typeIds));
                //if (ids.Count == 1)
                //{
                //    int tempTypeId = map[Config.IndexAlias].ItemTypeId;
                //    var checkVM = items.First(x => x.ItemType == tempTypeId);
                //    if (!rService.CheckData(int.Parse(checkVM.Value), checkVM.CreatedDate))
                //    {
                //        PMS.Log.Logger.Warnning("Recovery Mode:True");
                //        ids = new List<long>();
                //        var recoveryItems = context.Items.Select<Item>(rService.GetRecoverySql());
                //        if (!recoveryItems.Any())
                //        {
                //            PMS.Log.Logger.Error(new Exception("DbError"));
                //            return dt;
                //        }
                //        ids.Add(recoveryItems.First().ItemId);
                //        sql = getVMSql(filter, ref ids);
                //        items = context.Items.Select<ItemViewModel>(string.Format(ItemViewModel.QUERYSQL, sql, typeIds));
                //    }
                //}
                //else
                //{
                //    rService.IsRecoveryMode = false;
                //}
                var joinTypes = typeList.Where(x => x.ItemDataType.StartsWith("join")).ToList();
                StringBuilder templateNames = new StringBuilder();
                foreach (var item in items)
                {
                    templateNames.Append("'");
                    templateNames.Append(item.Name);
                    templateNames.Append("',");
                }
                List<TemplateJoinItemModel> templateIds;
                string names = "";
                if (templateNames.Length > 1)
                {
                    names = templateNames.ToString(0, templateNames.Length - 1);
                }

                if (isDisplay)
                {
                    templateIds = context.Items.Select<TemplateJoinItemModel>(string.Format(TemplateJoinItemModel.QuerySqlForDisplay, names, typeIds));
                }
                else
                {
                    templateIds = context.Items.Select<TemplateJoinItemModel>(string.Format(TemplateJoinItemModel.QuerySqlForPrint, names, typeIds));
                }
                templateIds = templateIds.Distinct().ToList();
                var queryIdsStr = string.Join(",", templateIds.Select(x => x.Id));
                var templates = context.Items.Select<TemplateViewModel>(string.Format(TemplateViewModel.QUERYSQL, queryIdsStr));
                var tempIds = items.Select(x => x.ItemId);
                foreach (var id in tempIds)
                {
                    if (ids.Contains(id)) continue;
                    ids.Add(id);
                }
                ids.Sort();
                foreach (var id in ids)
                {
                    var itemValues = items.Where(x => x.ItemId == id);
                    if (itemValues == null || !itemValues.Any()) continue;
                    var item = itemValues.First();
                    var itemTemplates = templates.Where(x => x.Name == item.Name);
                    var itsIds = itemTemplates.Select(x => x.Id);
                    itsIds = itsIds.Distinct();
                    foreach (var itsId in itsIds)
                    {
                        var templateModels = itemTemplates.Where(x => x.Id == itsId);
                        DataRow dr = dt.NewRow();                        
                        dr[mapDict[Config.NameAlias]] = item.Name;
                        dr[mapDict[Config.CreatedAlias]] = item.CreatedDate.ToString("yyyyMMdd");
                        dr["PrintStatus"] = item.PrintStatus;
                        dr["打印状态"] = item.ItemPrintStatus;
                        dr["ItemId"] = item.ItemId;
                        dr["TemplateFile"] = templateModels.First().TemplateFile;
                        int orderIndex = -1;
                        foreach (var iv in itemValues)
                        {
                            if (!typeDict.ContainsKey(iv.ItemType)) continue;
                            var it = typeDict[iv.ItemType];
                            var name = it.ItemName;
                            if (it.Alias == Config.IndexAlias)
                            {                                
                                string indexValue = iv.Value;
                                int tempLength = Config.IndexLength - indexValue.Length;
                                for (int j = 0; j < tempLength; j++)
                                {
                                    indexValue = "0" + indexValue;
                                }
                                orderIndex = int.Parse(iv.Value);
                                dr[name] = indexValue;
                            }
                            else
                                //dr[name] = ItemValueFacory.ConvertToValue(typeDict[iv.ItemType].ItemDataType, iv.Value, typeDict[iv.ItemType], dr);
                                dr[name] = iv.Value;
                        }

                        if (orderList != null && orderIndex > -1 && !orderList.ContainsKey(orderIndex))
                        {
                            orderList.Add(orderIndex, item.ItemId);
                        }                        
                        foreach (var itv in templateModels)
                        {
                            if (!typeDict.ContainsKey(itv.ItemType)) continue;
                            var it = typeDict[itv.ItemType];
                            var name = it.ItemName;
                            //dr[name] = ItemValueFacory.ConvertToValue(typeDict[itv.ItemType].ItemDataType, itv.Value, typeDict[itv.ItemType], dr);                            
                            dr[name] = itv.Value;
                        }
                        dt.Rows.Add(dr);
                        JoinRowsField(dr, joinTypes, mapDict);
                        
                    }
                }
            }
            ImportIds = null;
            dt.DefaultView.Sort = map[Config.IndexAlias].ItemName;
            //PMS.Log.Logger.Info("data is:/r/n" + dt.Rows[0].ItemArray);
            if (dt.Rows.Count > 0)
            {
                PMS.Log.Logger.Info("DataTable:"+dt.Rows[0][map[Config.IndexAlias].ItemName]);
            }
            else
            {
                PMS.Log.Logger.Info("DataTable:Empty");
            }
            return dt.DefaultView.ToTable();
        }

        public bool ImportTemplate(DataTable dt)
        {
            if (dt == null || dt.Rows.Count < 1) return true;
            List<string> columns = new List<string>();
            using (var context = new Db.Models.DbContext())
            {
                var typeList = context.Items.Select<ItemType>("select * from ItemType where ItemDataType not like 'ImportData%'");                
                var dict = typeList.ToDictionary(x => x.Alias);
                foreach (DataColumn dc in dt.Columns)
                {
                    if (dict.ContainsKey(dc.ColumnName))
                        columns.Add(dc.ColumnName);
                }
                columns.Remove(Config.BaseId);
                try
                {
                    var tran = context.Items.BeginTransaction();
                    foreach (DataRow dr in dt.Rows)
                    {
                        List<ItemTemplate> existNodes;
                        if (dt.Columns.Contains(Config.BaseId))
                            existNodes = context.Items.Select<ItemTemplate>("select * from ItemTemplate where ItemTemplateId=" + dr[Config.BaseId].ToString());
                        else
                            existNodes = new List<ItemTemplate>();
                        if (dt.Columns.Contains(Config.BaseId) && existNodes != null && existNodes.Any())
                        {
                            var node = existNodes.First();
                            Dictionary<string, string> fields = new Dictionary<string, string>();
                            foreach (var item in columns)
                            {
                                fields.Add(item, dr[item].ToString());
                            }
                            SaveItemTemplate(node.ItemTemplateId, dr[0].ToString(), dr[1].ToString(), fields, context);
                        }
                        else
                        {
                            var itemTemplate = new ItemTemplate();
                            itemTemplate.ItemTemplateName = dr[1].ToString();
                            itemTemplate.ItemTemplateFile = dr[0].ToString();
                            context.Items.Insert<ItemTemplate>(itemTemplate);
                            var templateId = context.Items.GetLastInsertId();
                            foreach (var item in columns)
                            {
                                var tValue = new ItemTemplateValue();
                                tValue.ItemTemplateId = (int)templateId;
                                tValue.Value = dr[item].ToString();
                                tValue.ItemTypeId = dict[item].ItemTypeId;
                                context.Items.Insert<ItemTemplateValue>(tValue);
                            }
                        }
                    }
                    tran.Commit();
                    tran.Dispose();
                }
                catch (Exception e)
                {
                    PMS.Log.Logger.Error(e);
                    return false;
                }
            }
            return true;
        }

        public void JoinRowsField(DataRow dr, List<ItemType> list, Dictionary<string,string> mapDict)
        {
            foreach (var item in list)
            {
                if (!dr.Table.Columns.Contains(item.ItemName)) continue;
                var value = dr[item.ItemName].ToString();
                if (!value.StartsWith("+") && !value.StartsWith("-")) continue;
                var flag = value.Substring(0, 1);
                value = value.Substring(1);
                var fields = value.Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries);
                var cellBuilder = new StringBuilder();
                foreach (var field in fields)
                {
                    if (!mapDict.ContainsKey(field))
                    {
                        continue;
                    }
                    var fieldName = mapDict[field];
                    cellBuilder.Append(dr[fieldName]);
                }
                if (flag == "-")
                {
                    dr[item.ItemName] = code.SaveToImage(cellBuilder.ToString());
                }
                else
                {
                    dr[item.ItemName] = cellBuilder.ToString();
                }
            }
        }



        public ItemType GetItemTypeById(int typeId)
        {
            using (var context = new DbContext())
            {
                var model = context.Items.QuerySingle<ItemType>("select * from ItemType where ItemTypeId=" + typeId.ToString());
                return model;
            }            
        }

        public ItemType GetItemTypeByAlias(string  alias)
        {
            using (var context = new DbContext())
            {
                var model = context.Items.QuerySingle<ItemType>("select * from ItemType where Alias='" + alias + "'");
                return model;
            }
        }

        public bool SaveItemType(ItemType model)
        {
            try
            {
                int id = 0;
                using (var context = new DbContext())
                {
                    var existNames = context.Items.Select<Models.ItemType>("select * from ItemType where ItemName='" + model.ItemName + "' and Alias != '" + model.Alias + "'");
                    if (existNames != null && existNames.Any()) return false;
                    if (model.ItemTypeId < 1)
                    {
                        var lastItem = context.Items.First<Models.ItemType>("Order by ItemTypeId desc");
                        int itemId = lastItem.ItemTypeId + 1;
                        model.ItemTypeId = itemId;
                        context.Items.Insert<ItemType>(model);
                        id = (int)context.Items.GetLastInsertId();
                    }
                    else
                    {
                        context.Items.Update<ItemType>(model);
                        id = model.ItemTypeId;
                    }
                }
            }
            catch (Exception e)
            {
                return false;
            }
            return true;
        }

        public bool SaveItemTemplate(int templateId,string fileName, string name, Dictionary<string, string> dict, DbContext context)
        {
                int id = 0;
                bool isUpdate = false;
                if (templateId < 1)
                {
                    ItemTemplate template = new ItemTemplate();
                    template.ItemTemplateName = name;
                    template.ItemTemplateFile = fileName;
                    context.Items.Insert(template);
                    id = (int)context.Items.GetLastInsertId();                    
                }
                else
                {
                    ItemTemplate template = context.Items.Select<ItemTemplate>("select * from ItemTemplate where ItemTemplateId="+templateId.ToString()).FirstOrDefault();
                    if (template == null) return false;
                    template.ItemTemplateFile = fileName;
                    template.ItemTemplateName = name;
                    id = templateId;
                    isUpdate = true;
                    context.Items.Update(template);
                }
                foreach (var item in dict)
                {
                    SaveItemTemplateValue(item.Key, item.Value, id, isUpdate, context);
                }
            
            return true;
        }

        public bool SaveItemTemplate(int templateId, string fileName, string name, Dictionary<string, string> dict)
        {
            using (var context = new DbContext())
            {
                int id = 0;
                bool isUpdate = false;
                if (templateId < 1)
                {
                    ItemTemplate template = new ItemTemplate();
                    template.ItemTemplateName = name;
                    template.ItemTemplateFile = fileName;
                    context.Items.Insert(template);
                    id = (int)context.Items.GetLastInsertId();
                }
                else
                {
                    ItemTemplate template = context.Items.Select<ItemTemplate>("select * from ItemTemplate where ItemTemplateId=" + templateId.ToString()).FirstOrDefault();
                    if (template == null) return false;
                    template.ItemTemplateFile = fileName;
                    template.ItemTemplateName = name;
                    id = templateId;
                    isUpdate = true;
                    context.Items.Update(template);
                }
                foreach (var item in dict)
                {
                    SaveItemTemplateValue(item.Key, item.Value, id, isUpdate, context);
                }
            }
            return true;
        }

        private bool SaveItemTemplateValue(string name, string value, int templateId, bool isUpdate, Models.DbContext context)
        {
            if (isUpdate)
            {
                var template = context.Items.Select<ItemTemplateValue>(string.Format("select * from ItemTemplateValue where ItemTypeId in (select ItemTypeId from ItemType where  Alias='{1}') and ItemTemplateId={0}", templateId, name)).FirstOrDefault();
                if(template==null) return false;
                template.Value = value;
                context.Items.Update(template);
            }
            else
            {
                var itemType = context.Items.Select<ItemType>(string.Format("select * from ItemType where Alias = '{0}'", name)).FirstOrDefault();
                if (itemType == null) return false;
                var model = new ItemTemplateValue();
                model.Value = value;
                model.ItemTemplateId = templateId;
                model.ItemTypeId = itemType.ItemTypeId;
                context.Items.Insert(model);
            }
            return true;
        }

        public bool SavePrintStatus(int id)
        {
            using (var context = new Models.DbContext())
            {
                try
                {

                    var item = context.Items.GetById<Item>(id);
                    item.ItemTemplateId = 1;
                    context.Items.Update(item);
                }
                catch (Exception)
                {
                    return false;
                }
            }
            return true;
        }

        public bool UpdateItemName(int id, string newName)
        {
            using (var context = new Models.DbContext())
            {
                try
                {
                    var templateList = context.Items.Select<ItemTemplate>(string.Format("select * from ItemTemplate where ItemTemplateName in ('{0}')", newName));
                    if (!templateList.Any()) return false;
                    var item = context.Items.GetById<Item>(id);
                    item.Name = newName;
                    context.Items.Update(item);
                }
                catch (Exception)
                {
                    return false;
                }
            }
            return true;
        }


    }

    public class RepIndexModel
    {
        public string Value { get; set; }
    }

    public class ItemIdModel
    {
        public int ItemId { get; set; }
    }
}
